oo::class create BreakPoint {
    superclass Plugin
    variable RenamedPadWidget Linum

    constructor {renamedPadWidget} {
        set RenamedPadWidget $renamedPadWidget
        set Linum [string trimleft $RenamedPadWidget _]Linum
        if [winfo exists $Linum] {
            $Linum tag configure breakpoint -background red
            bind $Linum <Double-1> [list [self object] flapBreakPoint %x %y]
        }
    }

    method flapBreakPoint {x y} {
        set id [$Linum index @$x,$y]
        my flapBreakPointAtIndex $id
    }

    method flapBreakPointAtIndex {id} {
        if [my ifTagedWithBreakPoint? $id] {
            my unsetBreakPoint $id
        } else {
            my setBreakPoint $id
        }
    }

    method setBreakPoint {id} {
        if [winfo exists $Linum] {
            $Linum tag add breakpoint "$id linestart" "$id +1l linestart"
        }
        $RenamedPadWidget tag add breakpoint "$id linestart" "$id +1l linestart"
    }

    method unsetBreakPoint {id} {
        if [winfo exists $Linum] {
            $Linum tag remove breakpoint "$id linestart" "$id +1l linestart"
        }
        $RenamedPadWidget tag remove breakpoint "$id linestart" "$id +1l linestart"
    }

    method ifTagedWithBreakPoint? {id} {
        foreach t [$Linum tag names $id] {
            if {$t == "breakpoint"} {return 1}
        }
        return 0
    }

    method updateBreakPoint {args} {
        if [winfo exists $Linum] {
            $Linum tag remove breakpoint 1.0 end
            foreach {head _} [$RenamedPadWidget tag ranges breakpoint] {
                $Linum tag add breakpoint "$head linestart" "$head +1l linestart"
            }
        }
    }

    method getPluginEvents {} {
        return {
            {afterInsert updateBreakPoint}
            {afterDelete updateBreakPoint}
            {afterReplace updateBreakPoint}
        }
    }
}